<template>
  <div class="flow-main-main">
    <div class="flow-main">
      <div class="flow-row">
        <div class="flow-node start-end">流程开始</div>
      </div>

      <div class="flow-row" v-for="(node, index) in flowNodes" :key="index">
        <div class="flow-node flow-arrows-2">
          <el-link type="primary" :underline="false" @click="addNode(index)"><i class="el-icon-circle-plus-outline"></i></el-link>
        </div>
        <div class="flow-node-arrows">
          <div class="flow-node">
            <div class="flow-item" v-for="(item, i) in node.items" :key="i">
              <div class="flow-tool">
                <el-input size="small" v-model="item.nodeName" placeholder="请输入审批节点名" :disabled="item.isLocked"/>
              </div>
              <el-divider></el-divider>
              <div class="flow-user">
                <el-input size="small" v-model="item.userName" placeholder="审批人" disabled>
                  <i v-if="!item.isLocked" slot="suffix" class="el-input__icon el-icon-search" @click="openUserDialog(item)"></i>
                </el-input>
              </div>
              <el-divider></el-divider>
              <div class="flow-tool flow-btn">
                <el-link type="primary" :underline="false" @click="addItem(index, i)"><i class="el-icon-circle-plus-outline"></i></el-link>
                <el-link v-if="!item.isLocked" type="danger" :underline="false" @click="deleteItem(index, i)"><i class="el-icon-delete"></i></el-link>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="flow-row">
        <div class="flow-node flow-arrows-2">
          <el-link type="primary" :underline="false" @click="addNode(flowNodes.length)"><i class="el-icon-circle-plus-outline"></i></el-link>
        </div>
        <div class="flow-node-arrows">
          <div class="flow-node start-end" style="border-radius: 50%;">流程结束</div>
        </div>
      </div>
    </div>
    <user-table ref="userTable" :multiple-mode="false" @set-value="setUsers"></user-table>
  </div>

</template>

<script>
import "./flow.scss";
import UserTable from "@/components/UserSelector/userTable";

export default {
  name: "Index",
  components: {
    UserTable
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    // 审批流程模板
    flowTempNodes: Array,
    // form表单数据
    formData: {
      type: Object,
      required: true
    }
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  data() {
    return {
      flowNodes: this.value,
      selectedNode: undefined,
      userOrgId: this.$store.state.user.orgId
    }
  },
  methods: {
    addNode(index) {
      const node = {
        items: [{
          nodeName: "审批",
          userName: undefined,
          userCode: undefined,
          isLocked: false
        }]
      };
      this.flowNodes.splice(index, 0, node);
      this.changeFlowNodes();
    },
    addItem(index, i) {
      const node = this.flowNodes[index];
      if (node) {
        const item = {
          nodeName: "审批",
          userName: undefined,
          userCode: undefined,
          isLocked: false
        };
        node.items.splice(i + 1, 0, item);
      }
      this.changeFlowNodes();
    },
    deleteItem(index, i) {
      const node = this.flowNodes[index];
      if (node) {
        const items = node.items;
        if (items.length > 1) {
          items.splice(i, 1);
        } else {
          this.flowNodes.splice(index, 1);
        }
      }
      this.$lodash.forEach(this.flowNodes, (item, index) => {
        item.orders = index + 1;
      });
      this.changeFlowNodes();
    },
    openUserDialog(item) {
      this.selectedNode = item;

      const users = [];
      if (item.userCode) {
        users.push({
          code: item.userCode,
          name: item.userName
        });
      }
      this.$refs.userTable.init(users);
    },
    setUsers(users) {
      if (users && users.length > 0) {
        this.$set(this.selectedNode, "userName", users[0].name);
        this.$set(this.selectedNode, "userCode", users[0].code);
      }
      this.changeFlowNodes();
    },
    setFlowNodes() {
      if (this.flowTempNodes && this.flowTempNodes.length > 0) {
        const flowTempNodes = JSON.parse(JSON.stringify(this.flowTempNodes));
        this.flowNodes = [];
        this.$lodash.forEach(flowTempNodes, tempNode => {
          const items = tempNode.items;
          if (this.hasConditions(items)) {
            // 有条件，按条件取
            this.chooseFlowItems(items);
          } else {
            // 没有条件，直接加入集合
            this.$lodash.forEach(items, item => {
              const nodes = item.nodes;
              this.setFlowItems(nodes);
            });
          }
        });
      }
      this.changeFlowNodes();
    },
    changeFlowNodes() {
      this.$lodash.forEach(this.flowNodes, (item, index) => {
        item.orders = index + 1;
      });
      this.$emit("change", this.flowNodes);
    },
    chooseFlowItems(items) {
      let defaultNodes = null;
      let nodes = null;
      this.$lodash.forEach(items, item => {
        const conditions = item.conditions;
        if (conditions && conditions.length > 0) {
          const formula = this.conditionFormula(conditions);
          if (eval(formula)) {
            nodes = item.nodes;
            return false;
          }
        } else {
          defaultNodes = item.nodes;
        }
      });

      if (nodes && nodes.length > 0) {
        this.setFlowItems(nodes);
      } else {
        this.setFlowItems(defaultNodes);
      }
    },
    conditionFormula(conditions) {
      const conditionList = [];
      this.$lodash.forEach(conditions, condition => {
        const items = [];
        this.$lodash.forEach(condition.conditionNodes, node => {
          const value = this.getFormValue(node.column, node.dataType);
          if (node.compare === 'in' || node.compare === 'not-in') {
            if (node.compare === 'in') {
              items.push(this.$lodash.findIndex(node.value, o => o === value) > -1);
            } else {
              items.push(this.$lodash.findIndex(node.value, o => o === value) <= -1);
            }
          } else {
            items.push(`${value} ${node.compareSymbol} ${this.getCompareValue(node.value, node.dataType)}`);
          }
        });
        conditionList.push(`(${items.join(" && ")})`);
      });
      return conditionList.join(" || ");
    },
    getFormValue(column, dataType) {
      if (column === "USER_ORG_ID") {
        return `'${this.userOrgId}'`;
      }
      const key = this.$lodash.camelCase(column);
      const value = this.formData[key];
      return this.getCompareValue(value, dataType);
    },
    getCompareValue(value, dataType) {
      if (dataType === 'NUMBER') {
        return this.$lodash.toNumber(value || 0);
      }
      return value ? `'${value}'` : '';
    },
    setFlowItems(nodes) {
      this.$lodash.forEach(nodes, node => {
        const newItems = [];
        const approvers = node.approvers;
        this.$lodash.forEach(approvers, approver => {
          newItems.push(approver);
        });
        this.flowNodes.push({
          items: newItems
        })
      })
    },
    hasConditions(items) {
      let has = false;
      this.$lodash.forEach(items, item => {
        if (item.conditions) {
          has = true;
          return false;
        }
      })
      return has;
    },
    checkConditionChanged(val, old) {
      // 值改变的key
      let changedKey = "";
      this.$lodash.forEach(val, (value, key) => {
        if (value !== old[key]) {
          changedKey = key;
          return false;
        }
      });

      // 是否条件字段的值改变了
      let conditionChanged = false;
      if (this.flowTempNodes && this.flowTempNodes.length > 0) {
        this.$lodash.forEach(this.flowTempNodes, tempNode => {
          const items = tempNode.items;
          if (this.hasConditions(items)) {
            this.$lodash.forEach(items, item => {
              const conditions = item.conditions;
              if (conditions && conditions.length > 0) {
                this.$lodash.forEach(conditions, condition => {
                  this.$lodash.forEach(condition.conditionNodes, node => {
                    const key = this.$lodash.camelCase(node.column);
                    if (key === changedKey) {
                      conditionChanged = true;
                      return false;
                    }
                  });
                });
              }
            });
          }
        });
      }
      return conditionChanged;
    }
  },
  watch: {
    value: {
      handler(val) {
        this.flowNodes = val;
      },
      deep: true
    },
    flowTempNodes: {
      handler() {
        this.setFlowNodes();
      },
      deep: true
    },
    formDataVal: {
      handler(val, old) {
        if (this.checkConditionChanged(val, old)) {
          this.setFlowNodes();
        }
      },
      deep: true
    }
  },
  computed: {
    formDataVal() {
      return JSON.parse(JSON.stringify(this.formData))
    }
  }
}
</script>

<style scoped lang="scss">

</style>
